package rand

import (
	"math/rand"
	"time"
)

func init() {
	rand.Seed(time.Now().UnixNano())
}

func Int(min, max int) int {

	if min == max {
		return min
	}

	return min + rand.Intn(max-min+1)
}

func Int32(min, max int32) int32 {

	if min == max {
		return min
	}

	return min + rand.Int31n(max-min+1)
}

func Int64(min, max int64) int64 {

	if min == max {
		return min
	}

	return min + rand.Int63n(max-min+1)
}

func Float64() float64 {
	return rand.Float64()
}

func Float32() float32 {
	return rand.Float32()
}

// 根据浮点数概率计算是否随机中奖
func IsWin(rate float32) bool {
	return rand.Float32() < rate
}

type Value interface {
	GetID() int32
	GetWeight() int32
}

type Struct struct {
	ID     int32
	Weight int32
}

func (s Struct) GetID() int32 {
	return s.ID
}

func (s Struct) GetWeight() int32 {
	return s.Weight
}

// 一组配置里随机不重复的N个出来
// 注意传入指针会改变其值
func WithWeight(configs []Value, n int) []Value {

	var res []Value

	for i := 0; i < n; i++ {

		if len(configs) == 0 {
			break
		}

		var conf = withWeight(configs)
		res = append(res, conf)

		var nextRound = make([]Value, 0, len(configs))
		for _, v := range configs {
			if v.GetID() == conf.GetID() {
				continue
			}
			nextRound = append(nextRound, v)
		}

		configs = nextRound
	}

	return res
}

// 传入数组长度 返回重排过的数组索引
func Shuffle(length int) []int {

	var arr = make([]int, length, length)
	for k := range arr {
		arr[k] = k
	}

	var res = make([]int, 0, length)

	for len(arr) > 0 {

		var index = rand.Intn(len(arr))
		res = append(res, arr[index])

		var temp = append(arr[0:index], arr[index+1:]...)
		arr = temp
	}

	return res
}

func withWeight(configs []Value) Value {

	var m = make(map[int]int32, len(configs))

	var sum int32 = 0
	for k, v := range configs {
		sum += v.GetWeight()
		m[k] = sum
	}

	var r = rand.Int31n(sum)

	for k, v := range configs {

		if r < m[k] {
			// 随到的就是你
			return v
		}
	}

	return configs[len(configs)-1]
}
